HTTP from ブラウザネットワーキング
3部 HTTP
10章 Webパフォーマンス入門
HTTP Archiveによれば、2013年時点で1アクセスで90リクエストを15のホストから取得、合計ファイルサイズは1300KB 画像がリクエスト数とデータサイズが大きい、次点でjavascript
1つのアクセスで起きるリクエストとデータサイズは右肩上がりで増大傾向
avashe.iconデータサイズは大きくなっているがリクエスト自体は2018年7月辺りから1段減った(なぜ?
webアプリはこれらダウンロードとDOM,CSSOMの構築、javascript実行という一連の「インストール」をアクセス毎に行い、数百msに納めなければならない
経験則としてはe2eのレイテンシを250ms程度で解決する必要がある
物理的に解決出来ずとも、ユーザインタラクションのレベルで先に応答することもあり
table:時間とユーザの知覚
遅延(ms) ユーザ知覚
0-100 瞬時
100-300 わずかに知覚可能な遅延
300-1000 マシンが動作している
1000+ メンタルコンテクストスイッチ(他のことが頭をよぎる)
10000+ タスク放棄
Webパフォーマンスは紙幣価値である
Bing検索では2000msの遅延はユーザの売上高を4.3%減らした Abardeenによる160以上の企業や団体に行った調査では、ロード時間に1秒の遅延が加わることで7%のコンバージョン、11%のページビュー、16%の顧客満足度低下 あまり鵜呑みにせず自身のサイトについてテストとベンチマークを構築せよ
HTTPの各ステージのレイテンシを可視化する計測ツールがあるよ
avashe.iconこういう記事ありますね
リソースのウォーターフォール効果
最初のHTMLの構文解析後に各要素のダウンロードが始まるので、リクエストは完全並行に始まらない
最初に静的なHTMLだけCDNで送りつけ、重要なコンテンツ部分や動的な部分をjavascriptで埋めとき、後からバックエンドの解析結果を送りつけて表示させるとかで対策
パフォーマンスボトルネックとしてのレイテンシ
5-6Mbps以上帯域を上げても標準的なwebページではほとんど性能が伸びない
TCP, DNS, HTTPなどの性質が往復=大きなレイテンシを生み出す
TCPのスロースタート
TCPとHTTPのHoLブロッキング
HTTPが細分化されたデータ群のバースト転送なのに、TCP自体は持続的な通信や、大きなデータを欠損無く送るために最適化されているので、そこに問題が生じている
パフォーマンスのテスト
システムそのものの挙動を知りたければローカルで、サイトの挙動を見たいならインフラの検証環境で、本番のe2eを見たければ監視サーバを各所に配置してテストやログを収集できる
しかし現実には全ての要因は集まらない
実際のユーザシナリオやナビゲーションパターン
ブラウザキャッシュの有無
プロキシやCDNなどの中間装置の存在
クライアントのハードウェア、ブラウザなどのソフトウェア
変動する帯域幅やレイテンシのジッタ
モバイルでは大きな問題
ユーザが実際に体験したログを分析し、パフォーマンス分析を補強する必要がある
W3CがRUMに有用な幾つかのAPIを標準化した
msの精度でDNSやTCPの接続時間のようなレイテンシの内訳を計測できる
ページ上の全てのリソースについて上記の計測が出来る
設定したアプリの指標について、精度の高いタイマーで計測できる
RUMに王道なし
アプリ特有のイベントやマイルストーンを定義、可視化し、対応するデータを集める
プロダクトやビジネスのオーナー、デザイナーや開発者など多くのステークホルダーが集まって議論すべき
ブラウザ最適化
主な手法
リソースの描画優先度とそれに対応したプリフェッチ
DNSプリフェッチ
接続しうるHTTPリクエストを分析し該当ホスト名を解決
ナビゲーション履歴やリンクホバーなどのインタラクションを利用する
加えてTCPの事前接続までやってしまう
ページプリレンダリング
次にアクセスする可能性が高いページを配信側が指定し、ブラウザが裏でレンダリングする
主な経験則
レンダリングとjsの実行のために最も早くCSSを配信すること
CSSやjsはドキュメント内で早く発見されるべき
重要度の低いjsの実行を後回しにする
HTMLドキュメントは徐々に解析されるためドキュメントは部分的であれ生成次第送信する
ブラウザによる投機最適化のヒントをドキュメントに加える
11章 HTTP 1.x
HTTP1.xの主な更新点(パフォーマンス面)
接続の再利用
レスポンスのストリーミング
並列リクエストを処理できるリクエストパイプライン
HoLブロッキングの制限などにより実質的に効果無し
バイト単位転送
HTTP運用のベストプラクティスは色々あるけど、結局ネットワークレイテンシの削減と、転送データ量の最小化が大事
DNSルックアップ回数、HTTPリクエスト数を減らす
CDNの利用
Expiresヘッダを追加し、Etagを設定することで必要なリソースをキャッシングする
リソースのGzip圧縮
異なるホストへのHTTPリダイレクトを避ける
HTTPキープアライブは重要
Nリクエストを送ると(N-1) × RTT分削減できる
3ウェイハンドシェイクの最後のAckにGETリクエストをのせると考えると、キープアライブは2回リクエストを送ると1往復分のレイテンシを減らすことができるから
2019年現在1ページのHTTPリクエスト数は50%tileで大体70強
秒単位でレイテンシが生じうる
HTTPパイプライン化は理想的には効果があるが現実的には使われていない
HTTP1.xは仕様上、1接続の中でHoLブロッキング(送った順番通りにレスポンスを返さないといけない)が起きる
複数まとめて送ってもサーバのバッファリングコストがかかる
並列処理しようにも先頭のリクエストが長い時間がかかる場合リクエストが詰まる
セキュリティリスク
まとめられたリクエストがこけた場合、どこまで進んだかが不明であるため、予め再送処理が冪等でなければならない
独自にサーバ・クライアント間がチューニングできるような環境なら恩恵が生まれうる
iTunesでは実際にHTTPパイプラインで高速化に成功している
汎用的なWebブラウザは無理なので、ほとんどがデフォルトでオフ
中間装置が対応していない問題はHTTPSで干渉を回避する
TCP多重化してHTTPを投げるのも困り物